﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.Text;
using System.Text.RegularExpressions;
using ProcessoSeletivo.DAO;

namespace ProcessoSeletivo.CA
{
    class Program
    {
        #region " Main "

        static void Main(string[] args)
        {
            bool ErroExecucao = false;
            bool flagEnviarEmail = false;
            string Assunto = "Processo Seletivo - FSBA";
            string Mensagem = "";
            string Arquivo = ConfigurationManager.AppSettings["Arquivo"];
            Dictionary<int, string> GabaritoOficial = new Dictionary<int, string>();
            DataView lDataView;

            try
            {
                Console.WriteLine("Iniciando a leitura dos gabaritos");

                using (StreamReader objReader = new StreamReader(Arquivo))
                {
                    string strLinha = "";

                    while (strLinha != null)
                    {
                        //Leitura de cada linha
                        strLinha = objReader.ReadLine();

                        //Remove os dados do gabarito
                        GabaritoOficial.Clear();

                        if (strLinha != null)
                        {
                            string inscricao = strLinha.Substring(0, 10);
                            string gabarito = strLinha.Substring(10, strLinha.Length - 12); //Extrai apenas as letras
                            int cod_candidato_can;
                            int count = 0;
                            double QtdCorreto = 0;
                            double QtdErrado = 0;
                            double QtdBranco = 0;
                            double QtdNulo = 0;

                            Console.WriteLine("Verificando o gabarito da inscrição " + inscricao);

                            inscricao = inscricao.Replace("20131", "00000");

                            //Consulta o gabarito correto para realizar a comparação
                            using (Gabarito objGab = new Gabarito())
                            {
                                lDataView = objGab.ListarGabaritoPorInscricao(Convert.ToInt32(inscricao));
                            }

                            foreach (DataRow lRow in lDataView.Table.Rows)
                            {
                                GabaritoOficial.Add(Convert.ToInt32(lRow["num_questao_que"].ToString()), lRow["des_letra_que"].ToString());
                            }

                            if (GabaritoOficial.Count > 0)
                            {
                                string nota_redacao = "";
                                double NotaRedacao = 0;
                                cod_candidato_can = Convert.ToInt32(lDataView.Table.Rows[0]["cod_candidato_can"]);

                                foreach (char caractere in gabarito)
                                {
                                    count++;

                                    if (char.IsLetter(caractere))
                                    {
                                        //Armazena a opção marcada pelo candidato
                                        using (QuestaoCandidato objQC = new QuestaoCandidato())
                                        {
                                            objQC.IncluirQuestaoCandidato(count, caractere, cod_candidato_can);
                                        }

                                        if (GabaritoOficial.ContainsKey(count))
                                        {
                                            if (GabaritoOficial[count].ToLower() == caractere.ToString().ToLower())
                                                QtdCorreto++;
                                            else if (GabaritoOficial[count] == "?")
                                                QtdCorreto++;
                                            else
                                                QtdErrado++;
                                        }
                                    }
                                    else
                                    {
                                        if (char.IsNumber(caractere))
                                        {
                                            nota_redacao += caractere;

                                            if (nota_redacao.Length == 2)
                                            {
                                                NotaRedacao = Convert.ToDouble(nota_redacao) / 10;

                                                //Armazenando a nota da redação
                                                using (Candidato objCan = new Candidato())
                                                {
                                                    objCan.AlterarCandidatoNotaRedacao(cod_candidato_can, NotaRedacao);
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (caractere == '@')
                                            {
                                                NotaRedacao = 10;

                                                //Armazenando a nota da redação
                                                using (Candidato objCan = new Candidato())
                                                {
                                                    objCan.AlterarCandidatoNotaRedacao(cod_candidato_can, 10);
                                                }
                                            }
                                            else
                                            {
                                                //Armazena a opção marcada pelo candidato
                                                using (QuestaoCandidato objQC = new QuestaoCandidato())
                                                {
                                                    objQC.IncluirQuestaoCandidato(count, caractere, cod_candidato_can);
                                                }

                                                if (GabaritoOficial.ContainsKey(count))
                                                {
                                                    if (GabaritoOficial[count] == "?")
                                                        QtdCorreto++;
                                                }
                                                else if (caractere == '*')
                                                    QtdBranco++;
                                                else if (caractere == '?')
                                                    QtdNulo++;
                                            }
                                        }
                                    }
                                }

                                //Necessário para saber a quantidade de questões objetivas
                                count--;

                                if (NotaRedacao < 10)
                                {
                                    count--;
                                }

                                double NotaFinal = Math.Round((QtdCorreto * 0.133) + NotaRedacao, 2);

                                //Armazenando a nota final
                                using (Candidato objCan = new Candidato())
                                {
                                    objCan.AlterarCandidatoNotaFinal(cod_candidato_can, NotaFinal);
                                }

                                Console.WriteLine("Questões corretas: " + QtdCorreto.ToString() + " questões incorretas: " + QtdErrado.ToString() + " questões em branco: " + QtdBranco.ToString() + " questões nulas: " + QtdNulo.ToString());

                                //Autorizando o envio do e-mail para os candidatos classificados
                                //flagEnviarEmail = true;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Ocorreu um erro durante o processamento. Descrição: " + ex.Message);

                flagEnviarEmail = false;
                ErroExecucao = true;

                Mensagem = "Ocorreu um erro durante o processamento das notas. <br>Mensagem: " + ex.Message + "<br>StackTrace: " + ex.StackTrace;
            }
            finally
            {
                if (flagEnviarEmail)
                {
                    //Verificar todos os aprovados e enviar e-mail
                    EnviarEmail(Assunto, "Teste", "shozer@gmail.com");
                }
                else if (ErroExecucao)
                {
                    //Enviar e-mail de erro para o suporte
                }
            }
        }

        #endregion

        #region " Demais métodos "

        private static void EnviarEmail(string Assunto, string Mensagem, string EmailTo)
        {
            try
            {
                Regex reEmail = new Regex(@"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*");

                // Pegando a imagem do site e adicionando no corpo da mensagem
                var webClient = new WebClient();
                byte[] imageBytes = webClient.DownloadData("http://processoseletivo.faculdadesocial.edu.br/img/logo.png");

                using (FileStream fs = File.Create(Environment.CurrentDirectory + @"\logo.png", imageBytes.Length))
                {
                    fs.Write(imageBytes, 0, imageBytes.Length);
                }

                string attachmentPath = Environment.CurrentDirectory + @"\logo.png";
                Attachment inline = new Attachment(attachmentPath);
                inline.ContentDisposition.Inline = true;
                inline.ContentDisposition.DispositionType = DispositionTypeNames.Inline;
                inline.ContentId = "logoFSBA";
                inline.ContentType.MediaType = "image/png";
                inline.ContentType.Name = Path.GetFileName(attachmentPath);

                // Montando a mensagem
                MailMessage objMensagem = new MailMessage();
                objMensagem.From = new MailAddress(ConfigurationManager.AppSettings["EmailFrom"], ConfigurationManager.AppSettings["NomeFrom"]);
                objMensagem.IsBodyHtml = true;
                objMensagem.Subject = Assunto;
                objMensagem.Body = Mensagem + "<div style=\"font-family:Arial\"><img src=\"cid:logoFSBA\" alt=\"\"></div>";
                objMensagem.Attachments.Add(inline);


                foreach (string item in EmailTo.Split(';'))
                {
                    if (item != "")
                    {
                        if (reEmail.IsMatch(item.Trim()))
                        {
                            objMensagem.To.Add(item.Trim());
                        }
                    }
                }

                //Enviando o e-mail
                using (SmtpClient client = new SmtpClient("smtp.gmail.com", 587))
                {
                    client.DeliveryMethod = SmtpDeliveryMethod.Network;
                    client.EnableSsl = true;
                    client.UseDefaultCredentials = false;

                    NetworkCredential credentials = new NetworkCredential("portal@faculdadesocial.edu.br", "isba!@ba");
                    client.Credentials = credentials;

                    client.Send(objMensagem);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Erro enviar e-mail: " + ex.Message);
                Console.WriteLine("StackTrace: " + ex.StackTrace);
                /*
                TextoLog += "\n\nErro no envio de e-mail!";
                TextoLog += "\n\nMensagem: " + ex.Message;
                TextoLog += "\n\nStackTrace: " + ex.StackTrace;

                Erro += "\n\nErro no envio de e-mail!";
                Erro += "\n\nMensagem: " + ex.Message;
                Erro += "\n\nStackTrace: " + ex.StackTrace;
                */
            }
            finally
            {
                //Necessário para continuar a execução mesmo que ocorra um erro.
            }
        }

        private static void MontarTable(ref string msg)
        {
            string table = "";
            bool flag = true;

            table += "<table style='border: 1px solid #95B3D7; text-align: center; font-size: 18px; font-weight: Bold; font-family: Arial, Verdana, sans-serif;'><tr><td>Relatório de rastreamento dos produtos - RBrain</td></tr></table>";
            table += "<br><br>";
            table += "<table style='border: 1px solid #95B3D7; font-size: 11px; font-family: Arial, Verdana, sans-serif;'>";
            table += "    <tr style='background-color: #4F81BD; color: #fff; font-weight: Bold; font-size: 12px;'>";
            table += "        <td>IDR</td> <td>CÓDIGO DE RASTREIO</td> <td>SITUAÇÃO</td> ";
            table += "    </tr>";

            //Loop para cada linha de dados
            foreach (string linha in msg.Split('#'))
            {
                if (linha != "")
                {
                    if (flag)
                    {
                        table += "    <tr style='background-color: #DCE6F1;'>";
                        flag = false;
                    }
                    else
                    {
                        table += "    <tr style='background-color: #fff;'>";
                        flag = true;
                    }

                    //Loop para cada coluna
                    foreach (string item in linha.Split(';'))
                    {
                        if (item != "")
                        {
                            table += "        <td>" + item + "</td>";
                        }
                    }

                    table += "    </tr>";
                }
            }

            table += "</table>";

            msg = table;
        }

        private static void CriarLog(string texto)
        {
            try
            {
                string caminho = Environment.CurrentDirectory + @"\log";
                string PrimeiraSubpasta = caminho + @"\" + DateTime.Now.ToString("yyyy");
                string SegundaSubpasta = PrimeiraSubpasta + @"\" + DateTime.Now.ToString("MM");
                string nomArquivo = DateTime.Now.ToString("dd_MM_yyyy_HH_mm") + ".txt";
                /*
                if (!String.IsNullOrEmpty(Erro))
                {
                    nomArquivo = "Erro_" + nomArquivo;
                }
                */
                //Criação da estrutura de pasta
                if (!Directory.Exists(caminho))
                {
                    Directory.CreateDirectory(caminho);
                }

                if (!Directory.Exists(PrimeiraSubpasta))
                {
                    Directory.CreateDirectory(PrimeiraSubpasta);
                }

                if (!Directory.Exists(SegundaSubpasta))
                {
                    Directory.CreateDirectory(SegundaSubpasta);
                }

                //Criação do arquivo do log
                using (FileStream fs = File.Create(SegundaSubpasta + @"\" + nomArquivo))
                {
                    using (StreamWriter sw = new StreamWriter(fs))
                    {
                        foreach (string frase in texto.Split('\n'))
                        {
                            if (frase != "")
                            {
                                sw.WriteLine(frase);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Ocorreu um erro na criação do log!");
                Console.WriteLine("Message: " + ex.Message);
                Console.WriteLine("StackTrace: " + ex.StackTrace);
            }
            finally
            {
                //Necessário para continuar a execução mesmo que ocorra um erro.
            }
        }

        #endregion
    }
}
